/*
 * Copyright (c) 2010, Oracle. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of Oracle nor the names of its contributors
 *   may be used to endorse or promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
package pt.iscte.iul.dcti.pa.gspas;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JButton;
import javax.swing.JLabel;

import pt.iscte.iul.dcti.pa.gspas.gui.GenericWindow;
import pt.iscte.iul.dcti.pa.gspas.gui.listener.CollectionMouseListener;
import pt.iscte.iul.dcti.pa.gspas.model.Course;
import pt.iscte.iul.dcti.pa.gspas.util.Property;
import pt.iscte.iul.dcti.pa.gspas.util.SwingUtils;

public class Main extends javax.swing.JFrame {

	private Object object;

	/**
	 * Creates new form Main
	 * 
	 * @param course
	 */
	public Main(Object course) {
		this.object = course;
		initComponents();
		loadComponentsFromModel();
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed"
	// desc="Generated Code">//GEN-BEGIN:initComponents
	private void initComponents() {

		jMenu1 = new javax.swing.JMenu();
		label1 = new java.awt.Label();
		jSeparator1 = new javax.swing.JSeparator();
		jPanel1 = new javax.swing.JPanel();
		jSplitPane1 = new javax.swing.JSplitPane();
		leftPanel = new javax.swing.JPanel();
		splitLeftPanel = new javax.swing.JSplitPane();
		top = new javax.swing.JPanel();
		bottom = new javax.swing.JPanel();
		panelRight = new javax.swing.JPanel();

		jMenu1.setText("jMenu1");

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle("PA - Project 2013");

		label1.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
		label1.setFont(new java.awt.Font("Dialog", 1, 18)); // NOI18N
		label1.setText("PA - Project 2013");

		jPanel1.setLayout(new java.awt.GridLayout(1, 0));

		splitLeftPanel.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);

		top.setLayout(new java.awt.GridLayout(3, 2));
		splitLeftPanel.setLeftComponent(top);

		org.jdesktop.layout.GroupLayout bottomLayout = new org.jdesktop.layout.GroupLayout(
				bottom);
		bottom.setLayout(bottomLayout);
		bottomLayout.setHorizontalGroup(bottomLayout.createParallelGroup(
				org.jdesktop.layout.GroupLayout.LEADING).add(0, 129,
				Short.MAX_VALUE));
		bottomLayout.setVerticalGroup(bottomLayout.createParallelGroup(
				org.jdesktop.layout.GroupLayout.LEADING).add(0, 252,
				Short.MAX_VALUE));

		splitLeftPanel.setRightComponent(bottom);

		org.jdesktop.layout.GroupLayout leftPanelLayout = new org.jdesktop.layout.GroupLayout(
				leftPanel);
		leftPanel.setLayout(leftPanelLayout);
		leftPanelLayout.setHorizontalGroup(leftPanelLayout
				.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
				.add(0, 131, Short.MAX_VALUE)
				.add(leftPanelLayout.createParallelGroup(
						org.jdesktop.layout.GroupLayout.LEADING).add(
						splitLeftPanel)));
		leftPanelLayout.setVerticalGroup(leftPanelLayout
				.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
				.add(0, 259, Short.MAX_VALUE)
				.add(leftPanelLayout.createParallelGroup(
						org.jdesktop.layout.GroupLayout.LEADING).add(
						splitLeftPanel)));

		jSplitPane1.setLeftComponent(leftPanel);

		org.jdesktop.layout.GroupLayout panelRightLayout = new org.jdesktop.layout.GroupLayout(
				panelRight);
		panelRight.setLayout(panelRightLayout);
		panelRightLayout.setHorizontalGroup(panelRightLayout
				.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
				.add(0, 409, Short.MAX_VALUE));
		panelRightLayout.setVerticalGroup(panelRightLayout.createParallelGroup(
				org.jdesktop.layout.GroupLayout.LEADING).add(0, 259,
				Short.MAX_VALUE));

		jSplitPane1.setRightComponent(panelRight);

		jPanel1.add(jSplitPane1);

		org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
				.add(jSeparator1)
				.add(org.jdesktop.layout.GroupLayout.TRAILING,
						layout.createSequentialGroup()
								.addContainerGap(248, Short.MAX_VALUE)
								.add(label1,
										org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
										org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
										org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
								.add(167, 167, 167))
				.add(layout
						.createParallelGroup(
								org.jdesktop.layout.GroupLayout.LEADING)
						.add(layout
								.createSequentialGroup()
								.addContainerGap()
								.add(jPanel1,
										org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
										org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
										Short.MAX_VALUE).addContainerGap())));
		layout.setVerticalGroup(layout
				.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
				.add(layout
						.createSequentialGroup()
						.add(label1,
								org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
								org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
								org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(
								org.jdesktop.layout.LayoutStyle.RELATED)
						.add(jSeparator1,
								org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
								10,
								org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
						.addContainerGap(285, Short.MAX_VALUE))
				.add(layout
						.createParallelGroup(
								org.jdesktop.layout.GroupLayout.LEADING)
						.add(org.jdesktop.layout.GroupLayout.TRAILING,
								layout.createSequentialGroup()
										.addContainerGap(61, Short.MAX_VALUE)
										.add(jPanel1,
												org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
												261,
												org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
										.addContainerGap())));

		pack();
	}// </editor-fold>//GEN-END:initComponents

	static Course course = new Course();

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[]) {
		/* Set the Nimbus look and feel */
		// <editor-fold defaultstate="collapsed"
		// desc=" Look and feel setting code (optional) ">
		/*
		 * If Nimbus (introduced in Java SE 6) is not available, stay with the
		 * default look and feel. For details see
		 * http://download.oracle.com/javase
		 * /tutorial/uiswing/lookandfeel/plaf.html
		 */
		try {
			javax.swing.UIManager.LookAndFeelInfo[] installedLookAndFeels = javax.swing.UIManager
					.getInstalledLookAndFeels();
			for (int idx = 0; idx < installedLookAndFeels.length; idx++) {
				if ("Nimbus".equals(installedLookAndFeels[idx].getName())) {
					javax.swing.UIManager
							.setLookAndFeel(installedLookAndFeels[idx]
									.getClassName());
					break;
				}
			}
		} catch (ClassNotFoundException ex) {
			java.util.logging.Logger.getLogger(Main.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (InstantiationException ex) {
			java.util.logging.Logger.getLogger(Main.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (IllegalAccessException ex) {
			java.util.logging.Logger.getLogger(Main.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		} catch (javax.swing.UnsupportedLookAndFeelException ex) {
			java.util.logging.Logger.getLogger(Main.class.getName()).log(
					java.util.logging.Level.SEVERE, null, ex);
		}
		// </editor-fold>
		/* Create and display the form */
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {

				course.setName("PA 2013");
				course.addAssignment("Project1");
				course.addStudent(1, "Ged");
				course.addStudent(2, "Simon");
				Main main = new Main(course);
				main.setVisible(true);

				// Get the size of the screen
				Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

				// Determine the new location of the window
				int w = main.getSize().width;
				int h = main.getSize().height;
				int x = (dim.width - w) / 2;
				int y = (dim.height - h) / 2;

				// Move the window
				main.setLocation(x, y);
				// main.setLocationRelativeTo(null);
			}
		});
	}

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JPanel bottom;
	private javax.swing.JMenu jMenu1;
	private javax.swing.JPanel jPanel1;
	private javax.swing.JSeparator jSeparator1;
	private javax.swing.JSplitPane jSplitPane1;
	private java.awt.Label label1;
	private javax.swing.JPanel leftPanel;
	private javax.swing.JPanel panelRight;
	private javax.swing.JSplitPane splitLeftPanel;
	private javax.swing.JPanel top;

	// End of variables declaration//GEN-END:variables
	private void loadComponentsFromModel() {
		// panelRight = new JPanel();
		// Common configuration
		Class<? extends Object> objectClass = object.getClass();
		String name = objectClass.getSimpleName();
		List<Property> properties = Property.getProperties(objectClass);
		panelRight.add(new JLabel(""));

		// JPanel panelLeft = new JPanel();
		int lineNumber = 0;

		for (final Property property : properties) {
			switch (property.getType()) {
			case BOOLEAN:
				top.add(SwingUtils.createLabel(property.getLabel()));
				top.add(SwingUtils.createBoolean("",
						property.getValue(object, Boolean.class)));
				lineNumber++;
				break;
			case INT:
				top.add(SwingUtils.createLabel(property.getLabel()));
				top.add(SwingUtils.createTxtField(property.getValue(object,
						int.class).toString()));
				lineNumber++;
				break;
			case DOUBLE:
				top.add(SwingUtils.createLabel(property.getLabel()));
				top.add(SwingUtils.createTxtField(property.getValue(object,
						int.class).toString()));
				lineNumber++;
				break;
			case ENUM:

				break;
			case STRING:
				top.add(SwingUtils.createLabel(property.getLabel()));
				top.add(SwingUtils.createTxtField(property.getValue(object,
						String.class)));
				lineNumber++;
				break;
			case COLLECTION:
				JLabel label;
				top.add(label = SwingUtils.createLabel(property.getLabel()));
				label.addMouseListener(new CollectionMouseListener(object,
						property, panelRight));
				top.add(SwingUtils.createLabel(""));
				lineNumber++;
				break;
			case VOID:
				final List<Property> propertiesArguments = property
						.getAddArgumentsProperties();
				if (propertiesArguments != null) {
					JButton button;
					bottom.add(button = SwingUtils.createButton(property
							.getLabel()));
					button.addActionListener(new java.awt.event.ActionListener() {
						@Override
						public void actionPerformed(
								java.awt.event.ActionEvent evt) {
							if (propertiesArguments.size() > 0) {
								btnActionPerformed(evt, propertiesArguments,
										property.getClazz(), property);
							} else {
								property.callAdd(object);
							}
						}
					});

					lineNumber++;
				}
				break;
			default:
				break;
			}
		}
		top.setLayout(new java.awt.GridLayout(lineNumber, 2));
		bottom.setLayout(new java.awt.GridLayout(lineNumber, 2));

	}

	private void btnActionPerformed(java.awt.event.ActionEvent evt,
			List<Property> propertiesArguments, Class<?> cls, Property property) {
		try {
			Object obj = cls.newInstance();
			new GenericWindow(this, object, obj, property, propertiesArguments)
					.setVisible(true);
		} catch (InstantiationException | IllegalAccessException ex) {
			Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

}
